package org.dawning.shop.order.command.aggregate;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.model.AggregateIdentifier;
import org.axonframework.commandhandling.model.AggregateMember;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.spring.stereotype.Aggregate;
import org.dawning.shop.common.commands.order.CancelOrderCommand;
import org.dawning.shop.common.commands.order.ConfirmOrderCommand;
import org.dawning.shop.common.vo.Address;
import org.dawning.shop.common.domain.order.OrderId;
import org.dawning.shop.common.domain.order.OrderProduct;
import org.dawning.shop.common.events.order.OrderCancelEvent;
import org.dawning.shop.common.events.order.OrderConfirmEvent;
import org.dawning.shop.common.events.order.OrderCreateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.Map;

import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;

/**
 * Created by miou on 2017/6/15 0015.
 */
@Aggregate
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderAggregate {

    private Logger logger = LoggerFactory.getLogger(OrderAggregate.class);

    @AggregateIdentifier
    private OrderId orderId;

    @AggregateMember
    private Map<String,OrderProduct> orderProducts;

    //购买人账号
    private String userAccount;

    //付款方式
    private String payWay;

    //订单状态
    private String status;

    //运费
    private BigDecimal freight;

    //总价
    private BigDecimal totalPrice;

    //收货地址
    private Address address;


    public OrderAggregate(OrderId id,String buyer,Map<String,OrderProduct> orderProducts,Address address){
        apply(new OrderCreateEvent(id,buyer,orderProducts,address));
    }

    /**取消订单命令处理器*/
    @CommandHandler
    public void on(CancelOrderCommand cancelOrderCommand){
        logger.info("apply cancel product command : " + cancelOrderCommand.toString());
        apply(new OrderCancelEvent(cancelOrderCommand.getOrderId(),cancelOrderCommand.getOrderProducts()));
    }

    /**确认订单命令生成器*/
    @CommandHandler
    public void on(ConfirmOrderCommand confirmOrderCommand){
        logger.info("apply confirmed product command : " + confirmOrderCommand.toString());
        apply(new OrderConfirmEvent(confirmOrderCommand.getOrderId()));
    }

    @EventHandler
    public void on(OrderCreateEvent event){
        this.orderId = event.getOrderId();
        this.orderProducts = event.getOrderProducts();
    }

}
